<ol>
<li><p >避免相关子查询</p>

<p >一个列的标签同时在主查询和where子句中的子查询中出现，那么很可能当主查询中的列值改变之后，子查询必须重新查询一次。
查询嵌套层次越多，效率越低，因此应当尽量避免子查询。如果子查询不可避免，那么要在子查询中过滤掉尽可能多的行。</p></li>
<li><p >避免困难的正规表达式</p>

<p >MATCHES和LIKE关键字支持通配符匹配，技术上叫正规表达式。但这种匹配特别耗费时间。例如:<code>SELECT * FROM customer WHERE zipcode LIKE "98_ _ _"</code>
即使在zipcode字段上建立了索引，在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM customer WHERE zipcode >“98000”，在执行查询时就会利用索引来查询，显然会大大提高速度。
另外，还要避免非开始的子串。例如语句:SELECT * FROM customer WHERE zipcode[2，3]>“80”，在where子句中采用了非开始子串，因而这个语句也不会使用索引。</p></li>
<li><p >使用临时表加速查询</p>

<p >把表的一个子集进行排序并创建临时表，有时能加速查询。它有助于避免多重排序操作，而且在其他方面还能简化优化器的工作。例如:</p>

<pre class='lang'><code class=''>SELECT cust.name，rcVBles.balance，……other columns
    FROM cust，rcvbles
        WHERE cust.customer_id = rcvlbes.customer_id
            AND rcvblls.balance&gt;0
            AND cust.postcode&gt;“98000
    ORDER BY cust.name;
</code></pre>

<p >如果这个查询要被执行多次而不止一次，可以把所有未付款的客户找出来放在一个临时文件中，并按客户的名字进行排序:</p>

<pre class='lang'><code class=''>SELECT cust.name，rcvbles.balance，……other columns
        FROM cust，rcvbles
                WHERE cust.customer_id = rcvlbes.customer_id
                    AND rcvblls.balance&gt;0
        ORDER BY cust.name
        INTO TEMP cust_with_balance;
</code></pre>

<p >然后以下面的方式在临时表中查询:</p>

<pre class='lang'><code class=''>SELECT * FROM cust_with_balance   WHERE postcode&gt;“98000”;
</code></pre>

<p >临时表中的行要比主表中的行少，而且物理顺序就是所要求的顺序，减少了磁盘I/O，所以查询工作量可以得到大幅减少。</p>

<p >注意:临时表创建后不会反映主表的修改。在主表中数据频繁修改的情况下，注意不要丢失数据。</p></li>
<li><p >尝试避免在频繁更新的表上执行复杂的SELECT查询，以避免与锁定表有关的由于读、写冲突发生的问题。</p></li>
<li><p >当不需要立即写入数据时，使用INSERT DELAYED。这样可以加快处理，因为很多记录可以通过一次磁盘写入被写入。</p></li>
<li><p >使用INSERT LOW_PRIORITY来取得插入队列的检索，也就是即使有另一个客户等待写入也要执行SELECT。</p></li>
<li><p >使用LOAD DATA INFILE装载较大数量的数据。这比使用INSERT要快得多。</p></li>
<li><p >查询语句中where  group by  order by中出现的列应尽量一致，以便每个子句都可以用到索引</p></li>
<li><p >尽量使用索引，通过explain分析进行优化</p></li>
<li><p >查询时使用匹配的类型。例如select * from a where id=5， 如果这里id是字符类型，同时有index，那么这条查询则使用不到index，会做全表扫描，速度会很慢。正确的应该是 … where id=”5” ，加上引号表明类型是字符。</p></li>
<li><p >使用--log-slow-queries –long-query-time=2查看查询比较慢的语句。然后使用explain分析查询，做出优化。</p></li>
<li><p >如果where条件中的列都有索引，但却不符合索引合并算法的要求，可以将条件拆分成两条select然后union，这样每条语句都可以用到索引。</p>

<p >例如：<code>SELECT * FROM orders WHERE (customer_num=104 AND order_num&gt;1001) OR order_num=1008;/*无法使用索引*/</code></p>

<p >修改为：<code>SELECT * FROM orders WHERE customer_num=104 AND order_num&gt;1001 UNION SELECT * FROM orders WHERE order_num=1008;</code></p></li>
<li><p >UNION ALL可以大大加快速度，如果你已经知道你的数据不会包括重复行，或者你不在乎是否会出现重复的行，在这两种情况下使用UNION ALL更适合。此外，还可以在应用程序逻辑中采用某些方法避免出现重复的行，这样UNION ALL和UNION返回的结果都是一样的，但UNION ALL不会进行排序</p></li>
<li><p >优化子查询</p></li>
</ol>
